package com.ly.system.controller;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.ly.common.core.bean.R;
import com.ly.common.core.bean.vo.TreeVO;
import com.ly.common.core.utils.excel.ExcelResult;
import com.ly.common.core.utils.excel.ExcelUtil;
import com.ly.system.service.*;
import com.ly.system.system.bean.entity.*;
import com.ly.system.system.bean.vo.SysUserRoleCountVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 角色
 *
 * @author jeecg
 * @since 2018-12-19
 */
@Tag(name = "角色")
@Slf4j
@RestController
@RequestMapping("/sys/role")
@RequiredArgsConstructor
public class SysRoleController {

    private final ISysRoleService sysRoleService;
    private final ISysPermissionDataRuleService sysPermissionDataRuleService;
    private final ISysRolePermissionService sysRolePermissionService;
    private final ISysPermissionService sysPermissionService;
    private final ISysUserRoleService sysUserRoleService;

    /**
     * 查询-id
     *
     * @param id
     * @return
     */
    @GetMapping("/getId")
    public R<SysRole> getId(@RequestParam(name = "id") String id) {
        return sysRoleService.getId(id);
    }

    /**
     * 列表
     *
     * @param entity
     * @return
     */
    @Operation(summary = "列表")
    @GetMapping("/getList")
    public R<List<SysRole>> getList(SysRole entity) {
        return sysRoleService.getList(entity);
    }

    /**
     * 分页
     *
     * @param entity
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Operation(summary = "分页")
    @GetMapping("/getPage")
    public R<IPage<SysRole>> getPage(
            SysRole entity,
            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        return sysRoleService.getPage(entity, new Page<SysRole>(pageNo, pageSize));
    }

    /**
     * 新增
     *
     * @param entity
     * @return
     */
    @PostMapping("/add")
    public R<String> add(@RequestBody SysRole entity) {
        return sysRoleService.add(entity);
    }

    /**
     * 编辑
     *
     * @param entity
     * @return
     */
    @PostMapping("/edit")
    public R<String> edit(@RequestBody SysRole entity) {
        return sysRoleService.edit(entity);
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @DeleteMapping("/delete")
    public R<String> delete(@RequestParam(name = "id") String id) {
        return sysRoleService.delete(id);
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @DeleteMapping("/deleteBatch")
    public R<String> deleteBatch(@RequestParam(name = "ids") String ids) {
        return sysRoleService.deleteBatch(ids);
    }

    /**
     * 校验角色编码唯一
     */
    @GetMapping("/checkRoleCode")
    public R<Boolean> checkUsername(String id, String roleCode) {
        // 如果此参数为false则程序发生异常
        log.info("--验证角色编码是否唯一---id:" + id + "--roleCode:" + roleCode);
        SysRole role = null;
        if (StrUtil.isNotEmpty(id)) {
            role = sysRoleService.getById(id);
        }
        // SysRole newRole = sysRoleService.getOne(new QueryWrapper<SysRole>().lambda().eq(SysRole::getRoleCode, roleCode));
        SysRole newRole = sysRoleService.getRoleNoTenant(roleCode);
        if (newRole != null) {
            // 如果根据传入的roleCode查询到信息了，那么就需要做校验了。
            if (role == null || !id.equals(newRole.getId())) {
                return R.fail(false,"角色编码已存在");
            }
        }
        return R.ok(true);
    }

    /**
     * 导出excel
     *
     * @param response
     */
    @Operation(summary = "导出excel")
    @GetMapping("/exportXls")
    public void exportXls(HttpServletResponse response) {
        List<SysRole> list = sysRoleService.list();
        ExcelUtil.exportExcel(list, "工作系数表", SysRole.class, response);
    }

    /**
     * 导入excel
     *
     * @param file
     * @param updateSupport：是否删除标识
     * @return
     */
    @Operation(summary = "导入excel")
    @PostMapping("/importExcel")
    public R<?> importWork(MultipartFile file, boolean updateSupport) throws Exception {
        // 监听： new ImportListener(updateSupport);
        ExcelResult<SysRole> result = ExcelUtil.importExcel(file.getInputStream(), SysRole.class, null);
        return R.ok(true, result.getAnalysis());
    }

    /**
     * 查询数据规则数据
     */
    @GetMapping("/datarule/{permissionId}/{roleId}")
    public R<?> loadDatarule(@PathVariable("permissionId") String permissionId, @PathVariable("roleId") String roleId) {
        List<SysPermissionDataRule> list = sysPermissionDataRuleService.getPermRuleListByPermId(permissionId);
        if (list == null || list.size() == 0) {
            return R.fail("未找到权限配置信息");
        }
        Map<String, Object> map = new HashMap(5);
        map.put("datarule", list);
        LambdaQueryWrapper<SysRolePermission> query = new LambdaQueryWrapper<SysRolePermission>()
                .eq(SysRolePermission::getPermissionId, permissionId)
                .isNotNull(SysRolePermission::getDataRuleIds)
                .eq(SysRolePermission::getRoleId, roleId);
        SysRolePermission sysRolePermission = sysRolePermissionService.getOne(query);
        if (sysRolePermission == null) {
            // return Result.error("未找到角色菜单配置信息");
        } else {
            String drChecked = sysRolePermission.getDataRuleIds();
            if (StrUtil.isNotEmpty(drChecked)) {
                map.put("drChecked", drChecked.endsWith(",") ? drChecked.substring(0, drChecked.length() - 1) : drChecked);
            }
        }
        return R.ok(map);
    }

    /**
     * 保存数据规则至角色菜单关联表
     */
    @PostMapping("/datarule")
    public R<?> saveDatarule(@RequestBody JSONObject jsonObject) {
        String permissionId = jsonObject.getString("permissionId");
        String roleId = jsonObject.getString("roleId");
        String dataRuleIds = jsonObject.getString("dataRuleIds");
        log.info("保存数据规则>>" + "菜单ID:" + permissionId + "角色ID:" + roleId + "数据权限ID:" + dataRuleIds);
        LambdaQueryWrapper<SysRolePermission> query = new LambdaQueryWrapper<SysRolePermission>()
                .eq(SysRolePermission::getPermissionId, permissionId)
                .eq(SysRolePermission::getRoleId, roleId);
        SysRolePermission sysRolePermission = sysRolePermissionService.getOne(query);
        if (sysRolePermission == null) {
            return R.fail("请先保存角色菜单权限!");
        } else {
            sysRolePermission.setDataRuleIds(dataRuleIds);
            this.sysRolePermissionService.updateById(sysRolePermission);
        }
        return R.ok("保存成功!");
    }

    /**
     * 用户角色授权功能，查询菜单权限树
     *
     * @return
     */
    @GetMapping("/getTree")
    public R<Map<String, Object>> getRoleTree() {
        // 全部权限ids
        List<String> ids = new ArrayList<>();
        LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
        query.orderByAsc(SysPermission::getSortNo);
        List<SysPermission> list = sysPermissionService.list(query);
        for (SysPermission sysPer : list) {
            ids.add(sysPer.getId());
        }
        List<TreeVO> treeList = new ArrayList<>();
        getTreeModelList(treeList, list, null);
        Map<String, Object> resMap = new HashMap(5);
        // 全部树节点数据
        resMap.put("treeList", treeList);
        // 全部树ids
        resMap.put("ids", ids);
        return R.ok(resMap);
    }

    private void getTreeModelList(List<TreeVO> treeList, List<SysPermission> metaList, TreeVO temp) {
        for (SysPermission permission : metaList) {
            String tempPid = permission.getParentId();
            TreeVO tree = new TreeVO(permission.getId(), tempPid, permission.getName(), permission.getRuleFlag(), permission.getLeaf());
            if (temp == null && StrUtil.isEmpty(tempPid)) {
                treeList.add(tree);
                if (ObjUtil.notEqual(tree.getIsLeaf(), true)) {
                    getTreeModelList(treeList, metaList, tree);
                }
            } else if (temp != null && tempPid != null && tempPid.equals(temp.getKey())) {
                temp.getChildren().add(tree);
                if (ObjUtil.notEqual(tree.getIsLeaf(), true)) {
                    getTreeModelList(treeList, metaList, tree);
                }
            }
        }
    }

    /**
     * 分页获取全部角色列表（包含每个角色的数量）
     *
     * @return
     */
    @GetMapping("/queryPageRoleCount")
    public R<IPage<SysUserRoleCountVo>> queryPageRoleCount(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                           @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        LambdaQueryWrapper<SysRole> query = new LambdaQueryWrapper<SysRole>();
        Page<SysRole> page = new Page<>(pageNo, pageSize);
        IPage<SysRole> pageList = sysRoleService.page(page, query);
        List<SysRole> records = pageList.getRecords();
        IPage<SysUserRoleCountVo> sysRoleCountPage = new PageDTO<>();
        List<SysUserRoleCountVo> sysCountVoList = new ArrayList<>();
        // 循环角色数据获取每个角色下面对应的角色数量
        for (SysRole role : records) {
            LambdaQueryWrapper<SysUserRole> countQuery = new LambdaQueryWrapper<>();
            countQuery.eq(SysUserRole::getRoleId, role.getId());
            long count = sysUserRoleService.count(countQuery);
            SysUserRoleCountVo countVo = new SysUserRoleCountVo();
            BeanUtils.copyProperties(role, countVo);
            countVo.setCount(count);
            sysCountVoList.add(countVo);
        }
        sysRoleCountPage.setRecords(sysCountVoList);
        sysRoleCountPage.setTotal(pageList.getTotal());
        sysRoleCountPage.setSize(pageList.getSize());
        return R.ok(sysRoleCountPage);
    }
}
